/**
 * Sign in box plugin.
 * @rebuildAt 2020.07.09 16:16
 * @author Randal
 * @depend layer message plugin.
 * @depend jquery element operator.
 * @depend noCaptcha plugin.
 * @depend AliLogTracker plugin for sign in behavior record.
 * @usage just call `toLogin(from)`.
 */
(function (window) {
    var SIGN_IN_METHOD_WE_CHAT = 'we-chat'
        , SIGN_IN_METHOD_QQ = 'qq'
        , SIGN_IN_METHOD_PHONE = 'phone'
        , SIGN_IN_METHOD_WEI_BO = 'wei-bo'
        , ALILOG_HOST = 'cn-shanghai.log.aliyuncs.com'
        , ALILOG_PROJECT = 'huke'
        , ALILOG_STORE = 'web-sign-in-behaviors-watcher';

    /**
     * 登录器插件
     * @var {object} plugin
     */
    var plugin = {
        positionTarget: '', // 登录器触发来源记录,
        methodTarget: '', // 登录方式触发记录,
        actionTarget: '', // 登录框操作触发记录,
        loggedUid: 0, // 登录成功UID,
        tracker: null,
        checkProcessing: false, // 请求处理状态

        /**
         * 初始化登录器
         */
        init: function () {
            this.registerBoxElementEvent();
            // phoneSignIn.init();
            // this.methodTarget = SIGN_IN_METHOD_PHONE;
            this.triggerContainer('switch')
            this.tracker = new logStrange(ALILOG_STORE, ALILOG_PROJECT, ALILOG_HOST);
            this.tracker.setCommonField('uv', Param.uv_id);
            this.tracker.setCommonField('uid', 0);
            this.tracker.setCommonField('request_url', Param.currentUrl);
        },

        /**
         * 注册登录器外围按钮事件
         */
        registerBoxElementEvent: function () {
            var self = this;

            // 头部登录注册按钮
            $("#loginBtn, #registerBtn").click(function () { self.globalSignIn('full-header') });

            // 微信登录按钮
            $(".lrframe-box-v1 .tab-main .we-chat-login-btn").click(function () { self.switchSignInMethod(SIGN_IN_METHOD_WE_CHAT) });

            // QQ登录按钮
            $(".lrframe-box-v1 .tab-main .qq-login-btn").click(function () { self.switchSignInMethod(SIGN_IN_METHOD_QQ) });

            // 手机号登录按钮
            $(".lrframe-box-v1 .tab-main .phone-login-btn").click(function () { self.switchSignInMethod(SIGN_IN_METHOD_PHONE) });

            // 微博登录按钮
            $(".lrframe-box-v1 .tab-main .wei-bo-login-btn").click(function () { self.switchSignInMethod(SIGN_IN_METHOD_WEI_BO) });

            //点击返回登录选择
            $(".lrframe-box-v1 .tab-main .go-back").click(function () { self.triggerContainer('switch') && self.resetSignInStatus(); });

            // 隐藏登录弹窗
            $('.lrframe-box-v1 span[data-bind-bs="hideModal"]').on('click', function () {
                $(this).parents('div.hkt-win').addClass('hide');
                self.triggerContainer('switch');
                self.resetSignInStatus();
                self.hitBox('close-popup');
                this.positionTarget = '';
            });

            //协议勾选
            $(".lrframe-box-v1 .agree-deal .cbx").click(function () {
                window.layer.msg('您需要同意协议才可以进行登录');
            });
        },

        /**
         * 全局登录方法, 需要暴露的唯一方法
         * 全局 toLogin = globalSignIn
         * @param {string} [from = ''] 触发来源, 用于登录器触发统计
         */
        globalSignIn: function (from) {
            this.positionTarget = from || '';
            $("#loginModal").removeClass("hide").attr('data-popup-extend','');
            this.hitBox('open-popup');
        },

        /**
         * 发送登录日志
         * @param {boolean} [sync = false] 是否同步执行
         */
        hit: function (sync) {
            this.tracker.setField('position', this.positionTarget, true);
            this.tracker.setField('method', this.methodTarget);
            this.tracker.setField('action', this.actionTarget);
            this.tracker.setField('uid', this.loggedUid);
            this.tracker.hit(sync);
        },

        /**
         * 发送登录弹窗日志
         * @param {string} action 操作描述
         */
        hitBox: function (action) {
            this.tracker.setField('position', this.positionTarget, true);
            this.tracker.setField('method', '');
            this.tracker.setField('action', action);
            this.tracker.hit();
        },

        /**
         * 登录方式选择器
         * @param {string} method 登录方式
         */
        switchSignInMethod: function (method) {
            this.methodTarget = method;
            this.actionTarget = 'trigger';
            this.hit();
            this.stopAllSignInChecker();
            switch (method) {
                case SIGN_IN_METHOD_WE_CHAT:
                    $('#loginModal').attr('data-popup-extend','we-chat');
                    return weChatSignIn.init();
                case SIGN_IN_METHOD_PHONE:
                    $('#loginModal').attr('data-popup-extend','phone');
                    return phoneSignIn.init();
                case SIGN_IN_METHOD_WEI_BO:
                case SIGN_IN_METHOD_QQ:
                    $('#loginModal').attr('data-popup-extend','qq');
                    return otherSignIn.checkSignIn(method);
                default:
                    return;
            }
        },

        /**
         * 触发登录方式选择器
         * @param {string} [container] 触发方式
         */
        triggerContainer: function (container) {
            if (['switch', 'phone-login-container', 'we-chat-container'].indexOf(container) === -1) {
                container = 'phone-login-container'
            }
            $('#loginModal .lrframe-box-v1 .tab-main .' + container).removeClass('hide').siblings().addClass('hide');
            return true;
        },

        /**
         * 返回按钮/关闭弹窗按钮事件处理
         */
        resetSignInStatus: function () {
            this.methodTarget = '';
            weChatSignIn.stopLoginCheck();
            phoneSignIn.reset();
            otherSignIn.stopChecking();
        },

        /**
         * 发送登录检查请求
         * @param {string} method 登录方式
         * @param {string} uniqueKey 登录唯一标识
         */
        sendCheckQuery: function (method, uniqueKey) {
            var self = this;
            !this.checkProcessing && $.ajax({
                url: Param.checkLogged,
                method: 'get',
                data: {unique_key: uniqueKey, method: method},
                xhrFields: {withCredentials: true},
                cache: false,
                success: function (data) {
                    if([200, 401].indexOf(data.code) !== -1) {
                        self.signInSuccess(data.signInAction, data.uid);
                    }
                    if (data.code !== 204) {
                        method === SIGN_IN_METHOD_WE_CHAT ?
                            weChatSignIn.stopLoginCheck(data.code !== 200) :
                            otherSignIn.stopChecking();
                    }
                    if (data.code === 200) {
                        window.location.reload();
                    } else if (data.code === 401) {
                        window.location.href = self.getBindingUrl();
                    } else if (data.code !== 204) {
                        window.layer.msg(data.message, {time: 0});
                    }
                },
                complete: function () {
                    self.checkProcessing = false;
                }
            });
            this.checkProcessing = true;
        },

        /**
         * 登录成功发送行为日志
         * @param {string} action 登录/注册动作标识
         * @param {int} [uid = 0] 登录/注册用户ID
         */
        signInSuccess: function (action, uid) {
            this.actionTarget = action;
            this.loggedUid = uid || 0;
            this.hit(true);
        },

        /**
         * 注册绑定成功触发登录行为统计
         * @param {string} method 注册方式
         * @param {string} position 登录注册触发位置
         * @param {int} uid 登录注册触发位置
         */
        bindingSuccess: function (method, position, uid) {
            this.actionTarget = 'binding';
            this.methodTarget = method;
            this.positionTarget = position;
            this.loggedUid = uid;
            this.hit(true);
        },

        /**
         * 获取绑定跳转URL
         * @return {string}
         */
        getBindingUrl: function () {
            return Url.bindUrl + '&position=' + this.positionTarget + '&method=' + this.methodTarget;
        },

        /**
         * 关闭所有登陆检查器
         */
        stopAllSignInChecker: function () {
            weChatSignIn.stopLoginCheck(false);
            otherSignIn.stopChecking();
        }
    };
    /**
     * 微信登录组件
     * @var {object} weChatSignIn
     */
    var weChatSignIn = {
        loginUniqueKey: '', // 登录唯一索引
        loginCheckTimer: 0, // 登录检查定时器

        /**
         * 初始化微信登录器
         */
        init: function () {
            plugin.triggerContainer('we-chat-container');
            this.getQrCode();
            this.beginSignInCheck();
        },

        /**
         * 发送获取二维码请求
         */
        getQrCode: function () {
            $(".lrframe-box-v1 .tab-main .we-chat").removeClass('hide').siblings().addClass('hide');
            $('.wx-qrcode').attr('src', Param.loginLoadingImg);

            var self = this;
            $.ajax({
                url: Param.weChatQrLoginUrl,
                method: 'get',
                dataType: 'json',
                xhrFields: {withCredentials: true},
                success: function (data) {
                    if (data.code === 200) {
                        self.loginUniqueKey = data.uniqueKey;
                        $('.wx-qrcode').attr('src', data.url);
                        self.sendReferrer(self.loginUniqueKey);
                    } else {
                        window.layer.msg(data.message);
                    }
                }
            });
        },

        /**
         * 发送用户Referrer记录请求
         * @param {string} key 登录唯一索引
         */
        sendReferrer: function (key) {
            $.ajax({
                url: Param.recordReferrer,
                method: 'get',
                data: {unique_key: key}
            });
        },

        /**
         * 初始化登录检查请求
         */
        beginSignInCheck: function () {
            var self = this;
            var tmpTimer = setInterval(function () {
                if (self.loginUniqueKey === '') {
                    return;
                }
                self.stopLoginCheck(false);
                self.loginCheckTimer = setInterval(plugin.sendCheckQuery.bind(plugin, SIGN_IN_METHOD_WE_CHAT, self.loginUniqueKey), 3000);
                clearInterval(tmpTimer);
            }, 1000);

            setTimeout(function () {
                window.layer.msg('超时了啦~ 刷新页面在试一次吧~', {time: 0});
                self.stopLoginCheck();
            }, 1000 * 1800);
        },

        /**
         * 停止微信登录检查器
         * @param {boolean} [resetImage = true] 是否重置二维码占位图片
         */
        stopLoginCheck: function (resetImage) {
            this.loginCheckTimer && clearInterval(this.loginCheckTimer);
            if (resetImage === undefined || !!resetImage) {
                $('.wx-qrcode').attr('src', Param.loginLoadingImg);
                this.loginUniqueKey = '';
            }
        }
    };
    /**
     * 手机登录组件
     * @var {object} phoneSignIn
     */
    var phoneSignIn = {
        hasInit: false, // 按钮事件初始化状态
        getCodeProcessing: false, // 请求短信验证码处理状态
        captchaData: {}, // 滑块验证数据
        noCaptchaSelector: '#no-captcha-of-login-container', // 滑块验证初始化选择器

        /**
         * 手机号登录组件初始化
         */
        init: function () {
            plugin.triggerContainer('phone-login-container');

            var self = this;
            var errorTimer = setTimeout(function () {
                window.layer.msg('验证组件加载失败, 请刷新页面重试');
            }, 2000);
            var tmpTimer = setInterval(function () {
                if (typeof aiCaptchaPlugin !== "object") {
                    return;
                }
                clearTimeout(errorTimer);
                aiCaptchaPlugin.init(self.noCaptchaSelector);
                clearInterval(tmpTimer);
            }, 200);

            this.hasInit = this.hasInit || this.initBtnEvent();
        },

        /**
         * 初始化手机登录按钮事件
         * @return {boolean}
         */
        initBtnEvent: function () {
            var self = this;

            // 手机输入框检测
            $('.lrframe-box-v1 input[name="phone"]').on('input propertychange', function () {
                var phoneNum = $(this).val().replace(/\D/g, '');
                $(this).val(phoneNum);
                if ($(this).val() > 11) {
                    $(this).val($(this).val().substr(0, 11));
                }
            });

            //点击手机号 登录/注册
            $(".lrframe-box-v1 .phone-btn").click(function () {
                var phoneNum = $(".lrframe-box-v1 .phone-num input").val();
                var code = $(".lrframe-box-v1 .yz-v1").val();

                //验证滑块是否触发
                if (phoneNum.length === 0) {
                    showTips("请输入手机号");
                    return false
                } else if (!self.checkTelNum(phoneNum)) {
                    showTips("手机号码错误");
                    return false;
                } else if (code.length === 0) {
                    showTips("请输入验证码");
                    return false;
                }
                var csrfToken = $('meta[name="csrf-token"]').attr("content");
                var data = {'_csrf-frontend': csrfToken};
                data.phone = phoneNum;
                data.code = code;
                data.verifyType = 2;

                $.ajax({
                    url: Url.phoneMessageLogin,
                    method: 'get',
                    data: data,
                    dataType: 'json',
                    xhrFields: {withCredentials: true},
                    success: function (data) {
                        if (data.code === 200) {
                            plugin.signInSuccess(data.signInAction, data.uid);
                            window.location.reload();
                        } else {
                            window.layer.msg(data.message);
                        }
                    }
                });
            });

            //获取验证码
            $(".lrframe-box-v1 .get-code").click(function () {
                // 检测是否在倒计时
                if ($(this).attr("disabled") === "disabled") {
                    showTips('请等待倒计时结束');
                    return false;
                }
                var phone = $(this).parents('.phone-m').find('.phone-num input').val();

                //验证滑块是否触发
                if (phone.length === 0) {
                    showTips("请输入手机号");
                    return false
                } else if (!self.checkTelNum(phone)) {
                    showTips('手机号码错误');
                    return false;
                } else if (self.getCodeProcessing) {
                    return false;
                }

                var csrfToken = $('meta[name="csrf-token"]').attr("content");
                var data = {'_csrf-frontend': csrfToken};
                data.phone = phone;
                data.verifyType = 2;
                data.nvcVal = aiCaptchaPlugin.getNVCVal();
                if (!Boolean(data.nvcVal)) {
                    showTips('登录环境异常请刷新页面重试');
                    return false;
                }
                self.getCodeProcessing = true;

                // 发送验证码
                $.ajax({
                    type: "get",
                    url: Url.sendMessage,
                    async: false,
                    data: data,
                    dataType: 'json',
                    success: function (data) {
                        if (typeof data.code === "number") {
                            $('.lrframe-box-v1 .phone-login-container').removeClass('no-slider');
                            aiCaptchaPlugin.getNC();
                            showTips('网络环境异常, 请拖动滑块验证');
                            return false;
                        }
                        if (data.state === 1) { // 发送成功
                            return self.countdown();
                        } else if (data.count === 5) {
                            self.getCodeProcessing = true;
                        }
                        self.reset();
                        showTips(data.msg);
                    },
                    complete: function () {
                        self.getCodeProcessing = false;
                    }
                });
            });

            return true;

            function showTips(str) {
                window.layer.msg(str);
                return false;
            }
        },

        /**
         * 发送短信验证码倒计时
         */
        countdown: function() {
            var self = this, $btn = $('.lrframe-box-v1 .get-code');
            $btn.addClass("ed").attr("disabled", "disabled");
            var seconds = 60, timer = setInterval(function () {
                $btn.val(--seconds + "s 后重新发送");
                if (seconds <= 0) {
                    $btn.removeClass("ed").val("获取验证码").attr("disabled", false);
                    self.reset();
                    clearInterval(timer);
                }
            }, 1000);
        },

        /**
         * 检查手机号
         * @param {string} mobile 手机号
         */
        checkTelNum: function (mobile) {
            var myreg = /^1[3456789]\d{9}$/;
            return myreg.test(mobile);
        },

        /**
         * 重置滑块验证
         */
        reset: function () {
            this.hasInit && aiCaptchaPlugin.reset();
        }
    };
    /**
     * 其他登录方式检查(异步登录)
     * @var {object} otherSignIn
     */
    var otherSignIn = {
        checkProcessing: false, // 检查登录请求状态
        checkingTimer: 0, // 检查登录定时器

        /**
         * 检查登录状态
         * @param {string} method
         */
        checkSignIn: function (method) {
            this.stopChecking();
            this.checkingTimer = setInterval(plugin.sendCheckQuery.bind(plugin, method), 3000);
        },

        /**
         * 结束检查
         */
        stopChecking: function () {
            this.checkingTimer && clearInterval(this.checkingTimer);
        }
    };

    /**
     * 日志存储处理器
     * @class logStrange
     * @param {string} store 日志库
     * @param {string} project 日志项目
     * @param {string} host 日志主机
     */
    var logStrange = function (store, project, host) {
        this.logStore = '//' + project + '.' + host + '/logstores/' + store + '/track?APIVersion=0.6.0';
        this.log = {};
        this.commonField = {};

        this.isIE = function () { return !!window.ActiveXObject || "ActiveXObject" in window; }
        this.getHttpClient = function () {
            var xhr;
            if (window.ActiveXObject) {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            } else if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest();
                xhr.timeout = 200;
            } else {
                throw window.Error("无法调用异步请求对象");
            }
            return xhr;
        }
    }

    /**
     * 设置日志通用字段
     * @param {string} key 日志字段名
     * @param {*} value 日志字段值
     * @return {void}
     */
    logStrange.prototype.setCommonField = function (key, value) {
        this.commonField[key] = value;
    }

    /**
     * 设置日志字段
     * @param {string} key 日志字段名
     * @param {*} value 日志字段值
     * @param {boolean} [renew = false] 是否刷新日志
     * @return {void}
     */
    logStrange.prototype.setField = function (key, value, renew) {
        if (renew === true) {
            this.log = {};
        }
        this.log[key] = value;
    }

    /**
     * 发送日志
     * @param {boolean} [async = true] 是否异步发送日志
     * @return {void}
     */
    logStrange.prototype.hit = function (async) {
        var url = this.logStore;
        var log = $.extend({}, this.commonField, this.log);
        for (var key in log) {
            if (log.hasOwnProperty(key) && typeof log[key] !== "undefined") {
                url += '&' + key + '=' + log[key].toString();
            }
        }
        try {
            var httpClient = this.getHttpClient();
            httpClient.open('GET', url, async === undefined || !!async);
            httpClient.send(null);
        } catch (e) {
            window.console.log('hit AliLog error with: \n', e);
        }
    }

    plugin.init();
    /** @function toLogin 全局登录方法 */
    window.toLogin = plugin.globalSignIn.bind(plugin);
    /** @function sendBindSuccess 绑定成功行为记录方法 */
    window.sendBindSuccess = plugin.bindingSuccess.bind(plugin);
})(window)
